<template>
  <div class="min-h-screen bg-gradient-to-br from-blue-50 to-purple-50 py-8">
    <div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
      <!-- Header -->
      <div class="text-center mb-8">
        <h1 class="text-3xl font-bold text-gray-900 mb-4">
          <span class="text-gradient">JSON 格式化 / 校验</span>
        </h1>
        <p class="text-lg text-gray-600">格式化、压缩与校验 JSON 文本，支持文件导入/导出与复制</p>
      </div>

      <!-- Tool Container -->
      <div class="bg-white rounded-xl shadow-lg p-6">
        <!-- Mode Selection -->
        <div class="mb-6">
          <div class="flex space-x-4">
            <button
              @click="mode = 'format'"
              :class="mode === 'format' ? 'primary-button' : 'secondary-button'"
              class="flex-1"
            >
              格式化
            </button>
            <button
              @click="mode = 'minify'"
              :class="mode === 'minify' ? 'primary-button' : 'secondary-button'"
              class="flex-1"
            >
              压缩
            </button>
            <button
              @click="mode = 'validate'"
              :class="mode === 'validate' ? 'primary-button' : 'secondary-button'"
              class="flex-1"
            >
              校验
            </button>
          </div>
        </div>

        <!-- Input Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">
            输入 JSON
          </label>
          <textarea
            v-model="inputText"
            placeholder="在此粘贴或输入 JSON 文本..."
            class="textarea-field h-40"
            @input="onInput"
          ></textarea>
          <div class="mt-2 text-sm text-gray-500">字符数: {{ inputText.length }}</div>
        </div>

        <!-- Output Area -->
        <div class="mb-6">
          <label class="block text-sm font-medium text-gray-700 mb-2">
            输出结果
          </label>
          <textarea
            v-model="outputText"
            readonly
            class="textarea-field h-40 bg-gray-50"
            :placeholder="placeholderOutput"
          ></textarea>
          <div class="mt-2 flex justify-between items-center">
            <span class="text-sm text-gray-500">字符数: {{ outputText.length }}</span>
            <div class="flex items-center space-x-3">
              <button @click="copyToClipboard" class="secondary-button text-sm py-2 px-4" :disabled="!outputText">
                {{ copied ? '已复制' : '复制结果' }}
              </button>
              <button @click="downloadResult" class="secondary-button text-sm py-2 px-4" :disabled="!outputText">
                下载结果
              </button>
            </div>
          </div>
        </div>

        <!-- Action Buttons -->
        <div class="flex flex-wrap gap-3 mb-4">
          <button @click="performOperation" class="primary-button" :disabled="!inputText">执行 ({{ modeLabel }})</button>
          <button @click="clearAll" class="secondary-button">清空内容</button>
          <button @click="loadSample" class="secondary-button">加载示例</button>
        </div>

        <!-- Options and File Actions -->
        <div class="mt-2 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
          <div class="flex items-center space-x-4">
            <label class="inline-flex items-center space-x-2 text-sm text-gray-700">
              缩进
              <select v-model.number="indentSize" class="form-select ml-2">
                <option :value="2">2</option>
                <option :value="4">4</option>
                <option :value="0">无</option>
              </select>
            </label>
          </div>

          <div class="flex items-center space-x-3">
            <button @click="triggerFileInput" class="secondary-button">从文件读取</button>
            <input ref="fileInputRef" type="file" class="hidden" accept=".json,text/*" @change="handleFileChange" />
            <button @click="pasteFromClipboard" class="secondary-button">从剪贴板粘贴</button>
          </div>
        </div>

        <!-- Error Message -->
        <div v-if="errorMessage" class="mt-4 p-3 bg-red-50 border border-red-200 rounded-lg">
          <p class="text-red-600 text-sm">{{ errorMessage }}</p>
        </div>
      </div>

      <!-- Instructions -->
      <div class="mt-8 bg-white rounded-xl shadow-lg p-6">
        <h3 class="text-lg font-semibold text-gray-900 mb-4">使用说明</h3>
        <ul class="space-y-2 text-gray-600">
          <li>• 选择要执行的操作：格式化、压缩或仅校验</li>
          <li>• 在上方输入框中粘贴或输入 JSON 内容</li>
          <li>• 点击「执行」或使用自动提示进行转换</li>
          <li>• 支持从文件读取或从剪贴板粘贴，支持下载结果</li>
        </ul>
      </div>

      <!-- Technical Info -->
      <div class="mt-6 bg-white rounded-xl shadow-lg p-6">
        <h3 class="text-lg font-semibold text-gray-900 mb-4">技术说明</h3>
        <div class="text-gray-600 text-sm space-y-2">
          <p>该工具基于浏览器的 JSON.parse 与 JSON.stringify 实现格式化与校验，支持 UTF-8 文本处理。</p>
          <p>如果输入不是合法 JSON，系统会给出解析错误并显示错误信息。</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, watch, computed } from 'vue'
import { useTools } from '@/composables/useTools'


const { copyToClipboard: toolsCopy, readFile, downloadFile } = useTools()

const mode = ref('format') // 'format' | 'minify' | 'validate'
const inputText = ref('')
const outputText = ref('')
const copied = ref(false)
const errorMessage = ref('')
const indentSize = ref(2)
const fileInputRef = ref(null)

const modeLabel = computed(() => {
  if (mode.value === 'format') return '格式化'
  if (mode.value === 'minify') return '压缩'
  return '校验'
})

const placeholderOutput = computed(() => {
  if (!inputText.value) return '执行后结果会显示在此处...'
  if (mode.value === 'validate') return '校验结果将显示在此处...'
  return '结果将显示在此处...'
})

const onInput = () => {
  // 自动校验（不会自动改写输入），仅在 validate 模式下自动执行
  errorMessage.value = ''
  if (mode.value === 'validate') {
    performOperation()
  }
}

const performOperation = () => {
  errorMessage.value = ''
  outputText.value = ''
  if (!inputText.value.trim()) return

  try {
    const parsed = JSON.parse(inputText.value)
    if (mode.value === 'format') {
      const space = indentSize.value > 0 ? indentSize.value : 0
      outputText.value = JSON.stringify(parsed, null, space)
    } else if (mode.value === 'minify') {
      outputText.value = JSON.stringify(parsed)
    } else {
      // validate
      outputText.value = 'JSON 校验通过'
    }
  } catch (err) {
    errorMessage.value = '解析失败：' + (err && err.message ? err.message : String(err))
    outputText.value = ''
  }
}

const copyToClipboard = async () => {
  if (!outputText.value) return
  try {
    const ok = await toolsCopy(outputText.value)
    if (ok) {
      copied.value = true
      setTimeout(() => (copied.value = false), 2000)
    } else {
    }
  } catch (err) {
  }
}

const clearAll = () => {
  inputText.value = ''
  outputText.value = ''
  errorMessage.value = ''
}

const loadSample = () => {
  inputText.value = '{"name":"Alice","age":30,"items":[1,2,3],"nested":{"ok":true}}'
  performOperation()
}

const triggerFileInput = () => {
  if (fileInputRef.value) fileInputRef.value.click()
}

const handleFileChange = async (e) => {
  const file = e.target.files && e.target.files[0]
  if (!file) return
  errorMessage.value = ''
  try {
    const text = await readFile(file)
    inputText.value = text
    performOperation()
  } catch (err) {
    errorMessage.value = '读取文件失败：' + (err && err.message ? err.message : String(err))
  } finally {
    e.target.value = ''
  }
}

const downloadResult = () => {
  if (!outputText.value) return
  const filename = mode.value === 'minify' ? 'json.min.json' : 'json.formatted.json'
  downloadFile(outputText.value, filename, 'application/json')
}

const pasteFromClipboard = async () => {
  try {
    const text = await navigator.clipboard.readText()
    if (text) {
      inputText.value = text
      performOperation()
    } else {
    }
  } catch (err) {
  }
}

// 监听模式变化时不自动清空，但在需要时可清理错误与输出
watch(mode, () => {
  errorMessage.value = ''
  outputText.value = ''
})

useHead({
  title: 'JSON 格式化 - 八八在线工具',
  meta: [
    { name: 'description', content: '在线 JSON 格式化、压缩与校验工具，支持文件导入导出与复制' }
  ]
})
</script>
